#include "TradeSignalHandler.h"
#include <spdlog/spdlog.h>
#include <sstream>
#include <cstring>

namespace MessageFramework {

// ==================== TradingSignalBody实现 ====================

TradingSignalBody TradingSignalBody::fromJson(const std::string& json) {
    TradingSignalBody signal;
    std::memset(&signal, 0, sizeof(signal));

    // 简化的JSON解析（生产环境应使用jsoncpp或rapidjson）
    auto extractString = [&](const std::string& key) -> std::string {
        std::string pattern = "\"" + key + "\":\"";
        size_t start = json.find(pattern);
        if (start == std::string::npos) return "";
        start += pattern.length();
        size_t end = json.find("\"", start);
        if (end == std::string::npos) return "";
        return json.substr(start, end - start);
    };

    auto extractDouble = [&](const std::string& key) -> double {
        std::string pattern = "\"" + key + "\":";
        size_t start = json.find(pattern);
        if (start == std::string::npos) return 0.0;
        start += pattern.length();
        size_t end = json.find_first_of(",}", start);
        if (end == std::string::npos) return 0.0;
        return std::stod(json.substr(start, end - start));
    };

    auto extractInt = [&](const std::string& key) -> int {
        std::string pattern = "\"" + key + "\":";
        size_t start = json.find(pattern);
        if (start == std::string::npos) return 0;
        start += pattern.length();
        size_t end = json.find_first_of(",}", start);
        if (end == std::string::npos) return 0;
        return std::stoi(json.substr(start, end - start));
    };

    std::strncpy(signal.instrumentId, extractString("instrumentId").c_str(),
                 sizeof(signal.instrumentId) - 1);
    std::strncpy(signal.direction, extractString("direction").c_str(),
                 sizeof(signal.direction) - 1);
    std::strncpy(signal.offsetFlag, extractString("offsetFlag").c_str(),
                 sizeof(signal.offsetFlag) - 1);
    signal.price = extractDouble("price");
    signal.volume = extractInt("volume");
    std::strncpy(signal.orderType, extractString("orderType").c_str(),
                 sizeof(signal.orderType) - 1);
    std::strncpy(signal.strategyId, extractString("strategyId").c_str(),
                 sizeof(signal.strategyId) - 1);
    std::strncpy(signal.comment, extractString("comment").c_str(),
                 sizeof(signal.comment) - 1);

    return signal;
}

std::string TradingSignalBody::toJson() const {
    std::ostringstream oss;
    oss << "{"
        << "\"instrumentId\":\"" << instrumentId << "\","
        << "\"direction\":\"" << direction << "\","
        << "\"offsetFlag\":\"" << offsetFlag << "\","
        << "\"price\":" << price << ","
        << "\"volume\":" << volume << ","
        << "\"orderType\":\"" << orderType << "\","
        << "\"strategyId\":\"" << strategyId << "\","
        << "\"comment\":\"" << comment << "\""
        << "}";
    return oss.str();
}

// ==================== TradeSignalHandler实现 ====================

TradeSignalHandler::TradeSignalHandler(SignalCallback callback)
    : m_callback(callback) {
}

void TradeSignalHandler::setCallback(SignalCallback callback) {
    m_callback = callback;
}

bool TradeSignalHandler::validateSignal(const TradingSignalBody& signal) const {
    // 1. 检查合约代码
    if (std::strlen(signal.instrumentId) == 0) {
        spdlog::error("Invalid signal: instrumentId is empty");
        return false;
    }

    // 2. 检查方向
    if (std::strcmp(signal.direction, "BUY") != 0 &&
        std::strcmp(signal.direction, "SELL") != 0) {
        spdlog::error("Invalid signal: direction must be BUY or SELL");
        return false;
    }

    // 3. 检查开平标志
    if (std::strcmp(signal.offsetFlag, "OPEN") != 0 &&
        std::strcmp(signal.offsetFlag, "CLOSE") != 0) {
        spdlog::error("Invalid signal: offsetFlag must be OPEN or CLOSE");
        return false;
    }

    // 4. 检查价格
    if (signal.price <= 0) {
        spdlog::error("Invalid signal: price must be positive");
        return false;
    }

    // 5. 检查数量
    if (signal.volume <= 0) {
        spdlog::error("Invalid signal: volume must be positive");
        return false;
    }

    // 6. 检查订单类型
    if (std::strlen(signal.orderType) == 0) {
        spdlog::error("Invalid signal: orderType is empty");
        return false;
    }

    // 7. 检查策略ID
    if (std::strlen(signal.strategyId) == 0) {
        spdlog::error("Invalid signal: strategyId is empty");
        return false;
    }

    return true;
}

int TradeSignalHandler::handleMessage(const Message& message) {
    spdlog::info("TradeSignalHandler processing message: {}", message.header.messageId);

    // 1. 解析消息体
    TradingSignalBody signal;
    try {
        signal = TradingSignalBody::fromJson(message.body);
    } catch (const std::exception& e) {
        spdlog::error("Failed to parse trading signal: {}", e.what());
        return -1;
    }

    // 2. 验证信号
    if (!validateSignal(signal)) {
        spdlog::error("Signal validation failed");
        return -2;
    }

    // 3. 调用回调处理信号
    if (m_callback) {
        try {
            int result = m_callback(signal, message.header);

            if (result == 0) {
                spdlog::info("Trading signal processed successfully: {} {} {} @ {}",
                           signal.direction, signal.offsetFlag,
                           signal.instrumentId, signal.price);
            } else {
                spdlog::warn("Trading signal processing failed with code: {}", result);
            }

            return result;

        } catch (const std::exception& e) {
            spdlog::error("Exception in signal callback: {}", e.what());
            return -3;
        }
    } else {
        spdlog::warn("No callback registered for TradeSignalHandler");
        return -4;
    }
}

} // namespace MessageFramework
